package com.demo.serialize;


import java.io.*;
import java.util.Scanner;

public class Tools {

    private static final String SOURCE_FILE_DEFAULT = System.getProperty("user.dir") + File.separator + "source.zip";
    private static final String TARGET_FILE_DEFAULT = System.getProperty("user.dir") + File.separator + "target.txt";
    private static String SOURCE_FILE = SOURCE_FILE_DEFAULT;
    private static String TARGET_FILE = TARGET_FILE_DEFAULT;
    private static String KEY = "779381333@qq.com";
    private final static Scanner SC = new Scanner(System.in);

    public static void main(String[] args){
        while (true) {
            showMenu();
        }

    }


    public static void showMenu(){
        System.out.println("==================序列化工具功能菜单=================");
        System.out.println("1.序列化文件");
        System.out.println("2.反序列化文件");
        System.out.println("q.退出系统");
        System.out.println("输入其他任意字符返回主菜单");
        System.out.println("请输入功能序号");
        String opt = SC.next();
        switch (opt){
            case "1": serializeMenu(0);break;
            case "2": serializeMenu(1);break;
            case "q": System.exit(0);
            default: showMenu();break;
        }

    }



    private static void serializeMenu(int type){
        String template = "进行文件相关参数配置操作(源输入文件路径,目标输出文件路径,加密Key(最短为16位)";
        if(type == 0){//序列化
            System.out.println(String.format(template,"序列化"));
        }else {//反序列化
            System.out.println(String.format(template,"反序列化"));
        }
        System.out.println("默认配置 源文件: 当前目录路径/source.zip,目标输出文件路径: 当前目录路径/target.txt");
        System.out.println("请输入功能序号");
        System.out.println("1.使用默认配置");
        System.out.println("2.使用自定义配置");
        System.out.println("输入其他任意字符返回主菜单");
        String opt = SC.next();
        switch (opt){
            case "1":
                defaultConfigure(type);
                break;
            case "2":
                customConfigure(type);
                break;
            default: showMenu();break;
        }



    }

    private static void customConfigure(int type){

        System.out.println("请输入源文件路径");
        SOURCE_FILE = SC.next();
        System.out.println("你输入的源文件路径为: " + SOURCE_FILE);
        System.out.println("请输入输出文件路径");
        TARGET_FILE = SC.next();
        System.out.println("你输入的输出文件路径为: " + TARGET_FILE);
        System.out.println("输入Y开始序列化,输入其他则进行序列化文件相关参数配置操作");
        String opt = SC.next();
        if(opt.equalsIgnoreCase("Y")){
            if(type == 0){
                serialize();
            }else {
                unSerialize();
            }
        }else {
            serializeMenu(type);
        }
    }

    /**
     * 恢复默认配置
     */
    private static void defaultConfigure(int type){

        if(type == 0){
            SOURCE_FILE = SOURCE_FILE_DEFAULT;
            TARGET_FILE = TARGET_FILE_DEFAULT;
            serialize();
        }else {
            SOURCE_FILE = TARGET_FILE_DEFAULT;
            TARGET_FILE = SOURCE_FILE_DEFAULT;
            unSerialize();
        }
    }


    /**
     * 反序列化
     */
    private static void unSerialize(){
        long startTime = System.currentTimeMillis();
        ObjectInputStream inputStream = null;
        OutputStream outputStream = null;
        byte[] b2 = new byte[0];
        try {
            inputStream = new ObjectInputStream(new FileInputStream(SOURCE_FILE));
            outputStream = new FileOutputStream(TARGET_FILE);
            byte[] b = new byte[1024];

            int len = 0;
            while((len = inputStream.read(b)) != -1){
                //将第一个数组
                if(b.length == len){
                    b2 = ByteCopyUtil.ByteMerge(b2,b);
                }else {
                    b2 = ByteCopyUtil.ByteMerge(b2,ByteCopyUtil.ByteSubstr(b,0,len));
                }
                outputStream.flush();

            }

            outputStream.write(AesUtil.decrypt(b2,KEY));
            outputStream.flush();


        }catch (IOException e){
            e.printStackTrace();
        }finally {
            System.out.println(String.format("文件大小:%sb,耗时:%s",b2.length,System.currentTimeMillis() - startTime));
            if(inputStream != null){
                try {
                    inputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if(outputStream != null){
                try {
                    outputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    /**
     * 序列化
     */
    private static void serialize(){
        long startTime = System.currentTimeMillis();
        ObjectOutputStream outputStream = null;
        InputStream inputStream = null;
        byte[] b2 = new byte[0];

        try {
            inputStream = new FileInputStream(SOURCE_FILE);
            outputStream = new ObjectOutputStream(new FileOutputStream(TARGET_FILE));
            byte[] b = new byte[1024];
            int len = 0;
            while((len = inputStream.read(b)) != -1){
                if(b.length == len){
                    b2 = ByteCopyUtil.ByteMerge(b2,b);
                }else{
                    b2 = ByteCopyUtil.ByteMerge(b2,ByteCopyUtil.ByteSubstr(b,0,len));
                }
            }
            outputStream.write(AesUtil.encrypt(b2,KEY));
            outputStream.flush();
        }catch (IOException e){
            e.printStackTrace();
        }finally {
            System.out.println(String.format("文件大小:%sb,耗时:%s",b2.length,System.currentTimeMillis() - startTime));

            if(inputStream != null){
                try {
                    inputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if(outputStream != null){
                try {
                    outputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }

        }
    }










}
